<?php
/**
 * @author       Sixe Team
 * @email        info@eee-eee.com
 * @url          http://www.eee-eee.com
 * @copyright    Copyright (C) 2010 - 2019 Sixe Information Technology Limited. All rights reserved.
 * @license      GNU General Public License version 2 or later; see LICENSE.txt
 * @date         2019/10/01 10:00
 */

defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;

jimport('joomla.application.component.modellist');

/**
 * Methods supporting a list of Rainbowpay records.
 *
 * @since  1.6
 */
class SixeWorkFlowModelArticles extends JModelList
{
	/**
	 * Constructor.
	 *
	 * @param   array $config An optional associative array of configuration settings.
	 *
	 * @see        JController
	 * @since      1.6
	 */
	public function __construct($config = array())
	{
		if (empty($config['filter_fields'])) {
			$config['filter_fields'] = array(
				'id', 'a.id',
				'state', 'a.state',
				'created', 'a.created',
				'created_by', 'a.created_by',
				'title', 'a.title',
				'author', 'a.author',
				'checked', 'rejected',
				'checked_name', 'rejected_name',
			);
		}

		parent::__construct($config);
	}

	/**
	 * Method to auto-populate the model state.
	 *
	 * Note. Calling getState in this method will result in recursion.
	 *
	 * @param   string $ordering Elements order
	 * @param   string $direction Order direction
	 *
	 * @return void
	 *
	 * @throws Exception
	 *
	 * @since    1.6
	 */
	protected function populateState($ordering = null, $direction = null)
	{
		// List state information.
		parent::populateState($ordering, $direction);
		$app = Factory::getApplication();

		$params = $app->getParams();
		$menuParams = new Registry;

		if ($menu = $app->getMenu()->getActive()) {
			$menuParams->loadString($menu->params);
		}

		$mergedParams = clone $menuParams;
		$mergedParams->merge($params);

		$this->setState('params', $mergedParams);
		$orderCol = $app->input->get('filter_order', 'a.id');

		if (!in_array($orderCol, $this->filter_fields)) {
			$orderCol = 'a.id';
		}

		$this->setState('list.ordering', $orderCol);

		$listOrder = $app->input->get('filter_order_Dir', 'ASC');

		if (!in_array(strtoupper($listOrder), array('ASC', 'DESC', ''))) {
			$listOrder = 'ASC';
		}

		$this->setState('list.direction', $listOrder);
		$state = $mergedParams->get('article_state', -1);
		$this->setState('filter.state', $state);

		$start = $app->input->get('limitstart', 0, 'int');
		$limit = $app->input->get('limit', $params->get('display_num'), 'int');

		if ($limit == 0) {
			$limit = $app->get('list_limit', 0);
		}

		$this->setState('list.limit', $limit);
		$this->setState('list.start', $start);
	}

	/**
	 * Build an SQL query to load the list data.
	 *
	 * @return   JDatabaseQuery
	 *
	 * @since    1.6
	 */
	protected function getListQuery()
	{
		// Create a new query object.
		$user = JFactory::getUser();
		$groups = implode(',', $user->groups);
		$db = $this->getDbo();
		$query = $db->getQuery(true);
		$subquery = '(SELECT COUNT(*) FROM #__workflow_users WHERE workflow_id=wc.workflow_id AND flow_id=c.flow AND 
 		((type=1 AND user_id IN(' . $groups . ')) OR (type=2 AND user_id=' . $user->id . '))) > 0 ';
		// Select the required fields from the table.
		$query
			->select('a.id,a.title,a.alias,a.catid,c.state,a.language,a.created,a.created_by_alias,a.attribs,a.created_by,a.access,a.publish_up,a.publish_down,a.hits,a.checked_out,a.checked_out_time,c.checked AS checked,c.rejected AS rejected,c.flow,c.start_flow');

		$query->from('#__workflow_contents AS c')
			->join('INNER', '#__workflow_categories AS wc ON wc.category_id=c.catid')
			//->where('(c.flow > c.start_flow AND '.$subquery.' )')
			->where('((c.created_by=' . $user->id . ' AND c.flow=c.start_flow) OR (c.flow > c.start_flow AND ' . $subquery . ' ))')
			->join('INNER', '#__content AS a ON a.id=c.content_id')
			->select("CASE WHEN a.created_by_alias > ' ' THEN a.created_by_alias ELSE u.name END AS author")
			->join('LEFT', '#__users AS u ON u.id = a.created_by')
			->select('ucheck.name AS checked_name,ureject.name AS rejected_name')
			->join('LEFT', '#__users AS ucheck ON ucheck.id=c.checked_by')
			->join('LEFT', '#__users AS ureject ON ureject.id=c.rejected_by');
		$state = $this->getState('filter.state', -1);

		if (is_numeric($state) && $state > -1) {
			$query->where('c.state=' . $state);
		}
		if (is_array($state) && count($state) && !in_array(-1, $state)) {
			$query->where('c.state IN (' . implode(',', $state) . ')');
		}


		$query->order($this->getState('list.ordering', 'a.id') . ' ' . $this->getState('list.direction', 'DESC'));

		return $query;
	}

	/**
	 * Method to get an array of data items
	 *
	 * @return  mixed An array of data on success, false on failure.
	 */
	public function getItems()
	{
		$items = parent::getItems();

		$user = JFactory::getUser();
		$userId = $user->get('id');
		$guest = $user->get('guest');
		$groups = $user->getAuthorisedViewLevels();
		$input = JFactory::getApplication()->input;

		// Get the global params
		$globalParams = JComponentHelper::getParams('com_content', true);

		// Convert the parameter fields into objects.
		foreach ($items as &$item) {
			$articleParams = new Registry($item->attribs);

			$item->params = clone $this->getState('params');
			$item->params->merge($articleParams);

			/**
			 * Compute the asset access permissions.
			 * Technically guest could edit an article, but lets not check that to improve performance a little.
			 */
			if (!$guest) {
				if ($this->getEditAccess($item->id)) {
					$item->params->set('access-edit', true);
				}
			}

			$item->flows = $this->getItemFlows($item->catid, $item->id);
			$item->userflow = $this->getFlow($item->catid, $user->id);
		}

		return $items;
	}

	/**
	 * Overrides the default function to check Date fields format, identified by
	 * "_dateformat" suffix, and erases the field if it's not correct.
	 *
	 * @return void
	 */
	protected function loadFormData()
	{
		$app = Factory::getApplication();
		$filters = $app->getUserState($this->context . '.filter', array());
		$error_dateformat = false;

		foreach ($filters as $key => $value) {
			if (strpos($key, '_dateformat') && !empty($value) && $this->isValidDate($value) == null) {
				$filters[$key] = '';
				$error_dateformat = true;
			}
		}

		if ($error_dateformat) {

			$app->setUserState($this->context . '.filter', $filters);
		}

		return parent::loadFormData();
	}

	/**
	 * Checks if a given date is valid and in a specified format (YYYY-MM-DD)
	 *
	 * @param   string $date Date to be checked
	 *
	 * @return bool
	 */
	private function isValidDate($date)
	{
		$date = str_replace('/', '-', $date);
		return (date_create($date)) ? Factory::getDate($date)->format("Y-m-d") : null;
	}


	public function getIs_Add()
	{
		$is_add = false;
		$user = JFactory::getUser();
		$groups = implode(',', $user->groups);
		$db = JFactory::getDbo();
		$query = $db->getQuery(true);
		$query->select('COUNT(DISTINCT a.workflow_id)')
			->from('#__workflow_users AS a')
			->where('(a.type=1 AND a.user_id IN (' . $groups . ')) OR (a.type=2 AND a.user_id=' . $user->id . ')');
		$db->setQuery($query);
		$is_add = $db->loadResult();
		return $is_add;
	}


	public function getEditAccess($id)
	{
		$return = false;
		$user = JFactory::getUser();
		$groups = implode(',', $user->groups);
		$db = JFactory::getDbo();

		$query = $db->getQuery(true);
		$query->select('COUNT(DISTINCT c.content_id)');
		$query->from('#__workflow_contents AS c')
			->where('c.content_id=' . $id)
			//->where('(SELECT COUNT(*) FROM #__workflow_flows WHERE content_id=c.content_id AND flow_id=c.flow) = 0')
			->join('INNER', '#__workflow_categories AS wc ON wc.category_id=c.catid')
			->join('INNER', '#__workflow_users AS wu ON wu.workflow_id = wc.workflow_id')
			->where('(c.created_by=' . $user->id . ' OR (((wu.type=1 AND wu.user_id IN (' . $groups . ') AND wu.flow_id=c.flow) OR (wu.type=2 AND wu.user_id=' . $user->id . ' AND wu.flow_id=c.flow)) AND c.flow > c.start_flow))');
		$db->setQuery($query);
		$content = $db->loadResult();
		if ($content > 0) {
			$return = true;
		}

		return $return;
	}


	function getItemFlows($catid, $id)
	{
		$return = array();
		$db = $this->getDbo();
		$query = $db->getQuery(true);
		$query->select('DISTINCT u.flow_id,u.title,uu.name AS check_name,f.checked ')
			->from('#__workflow_categories AS a')
			->join('LEFT', '#__workflow_users AS u ON u.workflow_id=a.workflow_id')
			->join('LEFT', '#__workflow_flows AS f ON (f.flow_id=u.flow_id AND f.content_id=' . $id . ')')
			->join('LEFT', '#__users AS uu ON uu.id=f.user_id')
			->where('a.category_id=' . $catid)
			->order('u.flow_id ASC');

		$db->setQuery($query);
		return $db->loadObjectList();
	}


	public function getFlow($catid, $user_id)
	{
		$user = JFactory::getUser($user_id);
		$groups = implode(',', $user->groups);
		$flow_id = array();
		$db = JFactory::getDbo();
		$query = $db->getQuery(true);
		$query->select('DISTINCT u.flow_id')
			->from('#__workflow_categories AS a')
			->join('LEFT', '#__workflow_users AS u ON u.workflow_id=a.workflow_id')
			->where('a.category_id=' . (int)$catid)
			->where('((u.type=1 AND u.user_id IN (' . $groups . ')) OR (u.type=2 AND u.user_id=' . $user->id . '))')
			->order('u.flow_id ASC');
		$db->setQuery($query);
		$temp = $db->loadColumn();
		if ($temp) {
			$flow_id = $temp;
		}

		return $flow_id;
	}
}
